package com.sy.utils;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.SerializationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Tuple;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

@Component
public class RedisClient {
    @Autowired
    private JedisPool jedisPool;

    public boolean set(String key, String value) {
        try (Jedis jedis = jedisPool.getResource()) {
            return "OK".equals(jedis.set(key, value));
        }
    }

    public boolean setObj(String key, Serializable value) {
        try (Jedis jedis = jedisPool.getResource()) {
            return "OK".equals(jedis.set(key.getBytes(), SerializationUtils.serialize(value)));
        }
    }

    public <T> T getObj(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            byte[] value = jedis.get(key.getBytes());
            if (!ArrayUtils.isEmpty(value)) {
                Object obj = SerializationUtils.deserialize(value);
                return (T) obj;
            }
        }
        return null;
    }

    public boolean setJson(String key, Object obj) {
        try (Jedis jedis = jedisPool.getResource()) {
            return "OK".equals(jedis.set(key, JSON.toJSONString(obj)));
        }
    }

    public <T> T getJsonObj(String key, Class<T> clazz) {
        try (Jedis jedis = jedisPool.getResource()) {
            //clazz是要转换出来的目标对象的类型
            return JSON.parseObject(jedis.get(key), clazz);
        }
    }

    public <T> List<T> getJsonObjList(String key, Class<T> clazz) {
        try (Jedis jedis = jedisPool.getResource()) {
            //clazz是目标集合中元素的泛型
            return JSON.parseArray(jedis.get(key), clazz);
        }
    }

    public void expire(String key, int expire) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.expire(key, expire);
        }
    }

    public boolean exists(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.exists(key);
        }
    }

    public boolean del(String... keys) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.del(keys) > 0;
        }
    }

    public int ttl(String key){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.ttl(key).intValue();
        }
    }

    public boolean lpush(String key,String...values){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.lpush(key,values) > 0;
        }
    }

    public  boolean rpush(String key,String...values){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.rpush(key,values) > 0;
        }
    }

    public  boolean lrem(String key, Long count, String value){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.lrem(key,count,value) > 0;
        }
    }

    public  List<String> lrange(String key, Long start, Long end){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.lrange(key, start, end);
        }
    }

    public  Long llen(String key){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.llen(key);
        }
    }

    public  Long hincrby(String key, String field, Long value){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hincrBy(key,field,value);
        }
    }

    public Map<String, String> hgetAll(String key){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hgetAll(key);
        }
    }

    public  Long hdel(String key, String... fields){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hdel(key,fields);
        }
    }

    public  Long hset(String key, String field, String value){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hset(key,field,value);
        }
    }

    public  String hget(String key, String field){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hget(key,field);
        }
    }

    public Long sadd(String key,String... values){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.sadd(key,values);
        }
    }

    public Set<String> smembers(String key, String... values){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.smembers(key);
        }
    }

    /**
     * 向redis中添加sorted set类型的数据
     */
    public long zadd(String key,double score,String member){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.zadd(key,score,member);
        }
    }

    /**
     * 对指定元素的分值递增
     */
    public Double zincrby(String key,double score,String member){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.zincrby(key,score,member);
        }
    }

    /**
     * 分值由高到低排列，获取分值和成员
     * @param key
     * @param startIndex 开始索引
     * @param endIndex 结束索引
     * @return
     */
    public Set<Tuple> zrevrangeWithScores(String key, long startIndex, long endIndex){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.zrevrangeWithScores(key,startIndex,endIndex);
        }
    }

    /**
     * 按分值倒序排列，获得该成员的排名
     * @param key
     * @param member
     * @return
     */
    public Long zrevrank(String key, String member){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.zrevrank(key,member) + 1;
        }
    }
}
